package cn.bjxy.shishaolong.system.user.controller;

import cn.bjxy.shishaolong.common.ResultMsg;
import cn.bjxy.shishaolong.common.StatusCode;
import cn.bjxy.shishaolong.common.SysConst;
import cn.bjxy.shishaolong.system.annotation.Permission;
import cn.bjxy.shishaolong.system.controller.AbstractController;
import cn.bjxy.shishaolong.system.exception.OperatorFailureException;
import cn.bjxy.shishaolong.system.service.IRoleService;
import cn.bjxy.shishaolong.system.user.entity.SysUserInfo;
import cn.bjxy.shishaolong.system.user.entity.SysUserLocalAuthen;
import cn.bjxy.shishaolong.system.user.service.ISysUserInfoService;
import cn.bjxy.shishaolong.system.user.service.ISysUserLocalAuthenService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * 用户控制器
 *
 * @Author 时少龙
 * @Date 2019-04-02 9:53
 * @Version 1.0
 */
@RestController
@CrossOrigin
@RequestMapping("/api/web/user")
@Slf4j
public class UserController extends AbstractController {

    @Autowired
    private ISysUserInfoService userInfoService;

    @Autowired
    private ISysUserLocalAuthenService authenService;

    @Autowired
    private IRoleService roleService;

    /**
     * 用户注册
     *
     * @param userInfo
     * @return
     */
    @PostMapping("/register")
    public ResultMsg register(@RequestBody SysUserInfo userInfo) {
        try {
            if (userInfo == null) {
                return ResultMsg.create(StatusCode.PARAMETER_ERROR, StatusCode.PARAMETER_ERROR_MSG);
            }
            // 判断若添加修改用户为管理员，要进行拦截
            if (roleService.judgeRole(userInfo.getRoleId(), SysConst.ROLE_KEY_SUPER_ADMIN, SysConst.ROLE_KEY_ADMIN)) {
                return ResultMsg.create(StatusCode.INSUFFICIENT_PRIVILEGE, StatusCode.INSUFFICIENT_PRIVILEGE_MESSAGE);
            }
            // 保存用户
            SysUserInfo registerUser = userInfoService.register(userInfo);
            if (registerUser == null) {
                return ResultMsg.create(StatusCode.RESGISTER_FAILURE, StatusCode.RESGISTER_MSG);
            }
            return ResultMsg.success(registerUser);
        } catch (OperatorFailureException ofe) {
            ofe.printStackTrace();
            return ResultMsg.create(ofe.getCode(), ofe.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMsg.create(StatusCode.SAVE_FAILURE, StatusCode.SAVE_FAILURE_MSG);
        }
    }

    /**
     * 保存用户  修改用户信息时用到
     *
     * @param userInfo
     * @return
     */
    @PostMapping("/save")
    @Permission
    public ResultMsg save(HttpServletRequest request, @RequestBody SysUserInfo userInfo) {
        try {
            if (userInfo == null) {
                return ResultMsg.create(StatusCode.PARAMETER_ERROR, StatusCode.PARAMETER_ERROR_MSG);
            }

            Integer currentUserId = getCurrentUserId(request);
            userInfo.setTid(currentUserId);
            if (!checkRoleIsAdmin(currentUserId)) { // 只对非管理员用户进行拦截
                // 判断若添加修改用户为管理员，要进行拦截
                if (roleService.judgeRole(userInfo.getRoleId(), SysConst.ROLE_KEY_SUPER_ADMIN, SysConst.ROLE_KEY_ADMIN)) {
                    return ResultMsg.create(StatusCode.INSUFFICIENT_PRIVILEGE, StatusCode.INSUFFICIENT_PRIVILEGE_MESSAGE);
                }

            }
            // 保存用户
            if (!userInfoService.save(userInfo)) {
                return ResultMsg.create(StatusCode.SAVE_FAILURE, StatusCode.SAVE_FAILURE_MSG);
            }
            return ResultMsg.success();
        } catch (OperatorFailureException ofe) {
            ofe.printStackTrace();
            return ResultMsg.create(ofe.getCode(), ofe.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMsg.create(StatusCode.SAVE_FAILURE, StatusCode.SAVE_FAILURE_MSG);
        }
    }

    /**
     * 微信修改用户信息
     *
     * @param userInfo
     * @return
     */
    @PostMapping("/wxSave")
    @Permission
    public ResultMsg wxSave(HttpServletRequest request, @RequestBody SysUserInfo userInfo) {
        try {
            Integer userId = getCurrentUserId(request);
            userInfo.setTid(userId);
            // 保存用户
            userInfoService.updateById(userInfo);
            return ResultMsg.success();
        } catch (OperatorFailureException ofe) {
            ofe.printStackTrace();
            return ResultMsg.create(ofe.getCode(), ofe.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMsg.create(StatusCode.SAVE_FAILURE, StatusCode.SAVE_FAILURE_MSG);
        }
    }


    /**
     * 获取用户信息
     *
     * @param request
     * @return
     */
    @RequestMapping("/getUserInfo")
    @Permission
    public ResultMsg getUserInfo(HttpServletRequest request) {
        try {
            Integer currentUserId = getCurrentUserId(request);
            log.debug("当前用户" + currentUserId.toString());
            SysUserInfo userInfo = userInfoService.getUserInfoById(currentUserId);
            if (Objects.isNull(userInfo)) {
                return ResultMsg.create(StatusCode.SERVER_INNER_ERROR, StatusCode.SERVER_INNER_ERROR_MSG);
            }
            return ResultMsg.success(userInfo);
        } catch (JwtException ex) {
            ex.printStackTrace();
            return ResultMsg.create(StatusCode.TOKEN_AUTHEN_FAILURE, StatusCode.TOKEN_AUTHEN_FAILURE_MSG);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMsg.create(StatusCode.SERVER_INNER_ERROR, StatusCode.SERVER_INNER_ERROR_MSG);
        }
    }

    /**
     * 检测旧密码是否正确
     *
     * @param authen 封装新旧密码的实体
     * @return 响应码，响应信息
     */
    @PostMapping("/checkPassword")
    @Permission
    public ResultMsg checkPassword(HttpServletRequest request, @RequestBody SysUserLocalAuthen authen) {
        try {
            if (authen == null || StringUtils.isEmpty(authen.getOldPassword())) {
                return ResultMsg.create(StatusCode.PARAMETER_ERROR, StatusCode.PARAMETER_ERROR_MSG);
            }
            /**
             * 获取用户工号，和userid
             */
            setUserIdAndNo(authen, request);
            if (!userInfoService.checkOldPassword(authen)) {
                return ResultMsg.create(StatusCode.OLD_PASSWORD_ERROR, StatusCode.OLD_PASSWORD_ERROR_MSG);
            }
            return ResultMsg.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMsg.create(StatusCode.SERVER_INNER_ERROR, StatusCode.SERVER_INNER_ERROR_MSG);
        }
    }

    /**
     * 修改用户密码
     *
     * @param authen
     * @return
     */
    @Permission
    @RequestMapping("/updatePassword")
    public ResultMsg updatePassword(HttpServletRequest request, @RequestBody SysUserLocalAuthen authen) {
        try {
            if (authen == null
                    // todo 涉及到密码认证，需要重新设计
                    || org.springframework.util.StringUtils.isEmpty(authen.getNewPassword())
                    || org.springframework.util.StringUtils.isEmpty(authen.getPasswdCheck())) {
                return ResultMsg.create(StatusCode.PARAMETER_ERROR, StatusCode.PARAMETER_ERROR_MSG);
            }

            /**
             * 获取用户工号，和userid
             */
            setUserIdAndNo(authen, request);
            authen.setPassword(authen.getNewPassword());
            userInfoService.updatePassword(authen);
            return ResultMsg.success();
        } catch (OperatorFailureException e) {
            e.printStackTrace();
            return ResultMsg.create(e.getCode(), e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultMsg.create(StatusCode.SERVER_INNER_ERROR, StatusCode.SERVER_INNER_ERROR_MSG);
        }
    }

    private void setUserIdAndNo(@RequestBody SysUserLocalAuthen authen, HttpServletRequest request) {
        Integer currentUserId = getCurrentUserId(request);
        authen.setUserId(currentUserId);
        SysUserLocalAuthen retAuthen = authenService.getOne(new QueryWrapper<SysUserLocalAuthen>().lambda()
                .isNull(SysUserLocalAuthen::getDeletedAt).eq(SysUserLocalAuthen::getUserId, currentUserId));
        authen.setNo(retAuthen.getNo());
    }

    /**
     * 判断用户是否为管理员
     *
     * @param userId
     * @return
     */
    private boolean checkRoleIsAdmin(Integer userId) {
        SysUserInfo user = userInfoService.getById(userId);
        return roleService.judgeRole(user.getRoleId(), SysConst.ROLE_KEY_ADMIN)
                || roleService.judgeRole(user.getRoleId(), SysConst.ROLE_KEY_SUPER_ADMIN);
    }
}
